﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Sedodream.Sudoku.Board;

namespace Sudoku.Web.MVC.Binders
{
    public class BoardBinder : IModelBinder
    {
        #region IModelBinder Members

        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (controllerContext == null) { throw new ArgumentNullException("controllerContext"); }
            if (bindingContext == null) { throw new ArgumentNullException("bindingContext"); }

            return BuildBoardFrom(bindingContext.ValueProvider);
        }

        protected IBoard BuildBoardFrom(IDictionary<string, ValueProviderResult> values)
        {
            if (values == null) { throw new ArgumentNullException("values"); }

            int?[,] boardData = new int?[9, 9];
            foreach (string key in values.Keys)
            {
                if (!string.IsNullOrEmpty(key) && key.StartsWith("row"))
                {
                    IPoint position = GetPointFromFieldName(key);
                    int? intValue = null;
                    string strValue = values[key].AttemptedValue;
                    if (!string.IsNullOrEmpty(strValue))
                    {
                        intValue = int.Parse(strValue);
                    }
                    boardData[position.Row, position.Col] = intValue;
                }
            }

            IBoard board = BoardFactory.CreateBoard(new BoardData(3, boardData));
            return board;
        }
        protected IPoint GetPointFromFieldName(string name)
        {
            if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); }

            string[] rowCol = name.Split('|');
            if (rowCol == null || rowCol.Length != 2)
            {
                //TODO: Change exception type
                string message = string.Format("Unexpected number of elements in the field [{0}]", name);
                throw new ApplicationException(message);
            }

            string rowStr = rowCol[0].Replace("row", string.Empty);
            string colStr = rowCol[1].Replace("col", string.Empty);

            IPoint result = new Point(int.Parse(rowStr), int.Parse(colStr));
            return result;
        }



        #endregion
    }
}
